/**
* Author: Georg Hofferek <georg.hofferek@iaik.tugraz.at>
*/
package at.iaik.suraq.smtlib.formula;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import sun.reflect.generics.reflectiveObjects.NotImplementedException;
import at.iaik.suraq.exceptions.IncomparableTermsException;
import at.iaik.suraq.sexp.Token;
import at.iaik.suraq.util.FormulaCache;
/**
* A formula consisting of the (in)equality of propositional terms.
*
* @author Georg Hofferek <georg.hofferek@iaik.tugraz.at>
*
*/
public class PropositionalEq extends EqualityFormula {
/**
*
*/
private static final long serialVersionUID = 3110446371682510102L;
/**
*
* Constructs a new <code>PropositionalEq</code>.
*
* @param terms
* the terms of the (in)equality.
* @param equal
* <code>true</code> if an equality should be constructed,
* <code>false</code> for an inequality.
*
*/
private PropositionalEq(Collection<? extends PropositionalTerm> propTerms,
boolean equal) {
super(propTerms, equal);
}
public static PropositionalEq create(
Collection<? extends PropositionalTerm> propTerms, boolean equal) {
return (PropositionalEq) FormulaCache.equalityFormula
.put(new PropositionalEq(propTerms, equal));
}
/**
* @see at.iaik.suraq.smtlib.formula.Formula#deepFormulaCopy()
*/
@Override
public Formula deepFormulaCopy() {
return this; // experimental
/*
* List<PropositionalTerm> terms = new ArrayList<PropositionalTerm>();
* for (Term term : this.terms) { terms.add((PropositionalTerm)
* term.deepTermCopy()); } return new PropositionalEq(terms, equal);
*/
}
/**
* @see at.iaik.suraq.smtlib.formula.Formula#tseitinEncode(java.util.List,
* java.util.Map)
*/
@Override
public PropositionalVariable tseitinEncode(List<OrFormula> clauses,
Map<PropositionalVariable, Formula> encoding,
Map<Formula, PropositionalVariable> done, int partition) {
List<ImpliesFormula> conjuncts = new ArrayList<ImpliesFormula>(2);
// A circle is enough:
// A = B = C
// A => B ^ B => C ^ C => A
PropositionalTerm term1 = (PropositionalTerm) terms.get(0);
for (int i = 1; i < terms.size(); i++) {
PropositionalTerm termi = (PropositionalTerm) terms.get(i);
conjuncts.add(ImpliesFormula.create(term1, termi));
}
PropositionalTerm termlast = (PropositionalTerm) terms
.get(terms.size() - 1);
conjuncts.add(ImpliesFormula.create(termlast, term1));
// old version:
/*
* assert (terms.size() == 2); PropositionalTerm term1 =
* (PropositionalTerm) terms.get(0); PropositionalTerm term2 =
* (PropositionalTerm) terms.get(1); // TODO: split larger equalities
*
* assert (clauses != null); assert (encoding != null);
*
* conjuncts.add(ImpliesFormula.create(term1, term2));
* conjuncts.add(ImpliesFormula.create(term2, term1));
*/
return (AndFormula.generate(conjuncts).tseitinEncode(clauses, encoding,
done, partition));
}
@Override
public Formula replaceEquivalences(Formula topLeveFormula,
Map<EqualityFormula, String> replacements,
Set<Token> noDependenceVars) {
ArrayList<Term> terms2 = new ArrayList<Term>();
for (int i = 0; i < terms.size(); i++) {
PropositionalTerm term = (PropositionalTerm) terms.get(i);
Formula newterm = term.replaceEquivalences(topLeveFormula,
replacements, noDependenceVars);
terms2.add((PropositionalTerm) newterm);
}
try {
return EqualityFormula.create(terms2, equal);
} catch (IncomparableTermsException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
/**
* @see at.iaik.suraq.smtlib.formula.Formula#getLiterals(java.util.Set,
* java.util.Set)
*/
@Override
public void getLiterals(Set<Formula> result, Set<Formula> done) {
for (Term term : terms) {
assert (term instanceof PropositionalTerm);
((PropositionalTerm) term).getLiterals(result, done);
}
}
/**
* @see at.iaik.suraq.smtlib.formula.Formula#numAigNodes(java.util.Set)
*/
@Override
public int numAigNodes(Set<Formula> done) {
throw new NotImplementedException();
}
/**
* @see at.iaik.suraq.smtlib.formula.Formula#toAig(TreeMap, java.util.Map)
*/
@Override
public int toAig(TreeMap<Integer, Integer[]> aigNodes,
Map<Formula, Integer> done) {
throw new NotImplementedException();
}
/**
* @see at.iaik.suraq.smtlib.formula.EqualityFormula#computeParents(java.util.Map,
* java.util.Set)
*/
@Override
public void computeParents(Map<Formula, Set<Formula>> parents,
Set<Formula> done) {
for (Term term : terms) {
assert (term instanceof PropositionalTerm);
PropositionalTerm propTerm = (PropositionalTerm) term;
Set<Formula> childsParents = parents.get(propTerm);
if (childsParents == null) {
childsParents = new TreeSet<Formula>();
parents.put(propTerm, childsParents);
}
assert (childsParents != null);
childsParents.add(this);
propTerm.computeParents(parents, done);
}
done.add(this);
}
/**
* @see at.iaik.suraq.smtlib.formula.EqualityFormula#dependsOnlyOn(java.util.Set)
*/
@Override
public boolean dependsOnlyOn(Set<Formula> formulaSet) {
Set<Formula> propTerms = new HashSet<Formula>(terms.size() * 2);
for (Term term : terms) {
assert (term instanceof PropositionalTerm);
propTerms.add((PropositionalTerm) term);
}
boolean result = formulaSet.containsAll(propTerms);
return result;
}
/**
* @see at.iaik.suraq.smtlib.formula.Formula#getTerms(java.util.Set,
* java.util.Set)
*/
@Override
public void getTerms(Set<Term> result, Set<Formula> done) {
if (done.contains(this))
return;
for (Term term : terms) {
assert (term instanceof PropositionalTerm);
((PropositionalTerm) term).getTerms(result, done);
}
done.add(this);
}
}